#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import os
os.environ['TK_SILENCE_DEPRECATION'] = '1'  # 消除TK警告

import tkinter as tk
from tkinter import scrolledtext, messagebox, ttk
import threading
import time
import pyautogui
# 恢复backup版本的设置，确保拖拽操作被正确识别
import cv2
import numpy as np
import json
import easyocr
import os
from typing import Dict, List, Tuple, Optional
from generals_enum import AVAILABLE_GENERALS, get_all_general_names, load_generals_from_directory

class UnifiedSmartRecognizer:
    """一体化智能武将管理系统 - 集成区域标定和识别功能"""
    
    def __init__(self):
        pyautogui.PAUSE = 0.1
        pyautogui.FAILSAFE = False
        
        # 获取分辨率信息
        self.logical_width, self.logical_height = pyautogui.size()
        screenshot = pyautogui.screenshot()
        self.physical_width, self.physical_height = screenshot.width, screenshot.height
        self.scale_x = self.physical_width / self.logical_width
        self.scale_y = self.physical_height / self.logical_height
        
        print(f"逻辑分辨率: {self.logical_width}x{self.logical_height}")
        print(f"物理分辨率: {self.physical_width}x{self.physical_height}")
        print(f"缩放比例: {self.scale_x:.1f}x{self.scale_y:.1f}")
        
        # 初始化OCR
        self.init_ocr()
        
        # 区域数据
        self.regions = {
            'camp': {'top_left': None, 'bottom_right': None, 'name': '营帐区域'},
            'battlefield': {'top_left': None, 'bottom_right': None, 'name': '上阵区域'},
            'hand': {'top_left': None, 'bottom_right': None, 'name': '手牌区域'}
        }
        
        # 尝试加载已有的区域标定数据
        self.load_region_calibration()
        
        # 加载武将列表
        self.load_general_list()
        
        # 识别结果存储
        self.region_generals = {
            'camp': [],
            'battlefield': [],
            'hand': []
        }
        
        # 选择的武将
        self.selected_generals = {
            'camp': set(),
            'battlefield': set(),
            'hand': set()
        }
        
        # 界面状态
        self.calibration_mode = False
        
        # 速度设置
        self.speed_setting = 3
        
        # 空格键防抖
        self.last_space_press = 0
        
        # 控制变量
        self.running = False
        
        # 创建GUI
        self.create_gui()
        
    def init_ocr(self):
        """初始化OCR"""
        try:
            self.ocr_reader = easyocr.Reader(['ch_sim', 'en'], gpu=False)
            print("✅ OCR初始化成功")
        except Exception as e:
            print(f"❌ OCR初始化失败: {e}")
            self.ocr_reader = None
            
    def load_region_calibration(self):
        """加载区域标定数据"""
        try:
            with open("region_calibration.json", "r", encoding="utf-8") as f:
                self.calibration_data = json.load(f)
            self.regions = self.calibration_data['regions']
            print(f"✅ 已加载区域标定数据")
        except Exception as e:
            print(f"⚠️ 未找到区域标定数据，将进入标定模式")
            self.calibration_data = None
            self.calibration_mode = True
            
    def load_general_list(self):
        """加载武将列表"""
        # 使用武将枚举中的数据
        self.available_generals = get_all_general_names()
        print(f"📋 从枚举加载了 {len(self.available_generals)} 个武将")
        
        # 验证与实际文件的一致性
        actual_generals = load_generals_from_directory("游戏资料/武将图片")
        print(f"📁 从目录加载了 {len(actual_generals)} 个武将文件")
        
        if len(actual_generals) > 0:
            # 显示文件目录对比信息（仅供参考）
            missing_in_enum = set(actual_generals) - set(self.available_generals)
            missing_files = set(self.available_generals) - set(actual_generals)
            
            if missing_in_enum:
                print(f"📁 文件中额外的武将: {missing_in_enum}")
            if missing_files:
                print(f"📋 枚举中额外的武将: {missing_files}")
                
            print("🎯 使用枚举武将列表（不依赖文件目录）")
        else:
            print("⚠️ 未找到武将图片文件目录")
            
        print(f"✅ 已加载 {len(self.available_generals)} 个武将")
        if len(self.available_generals) > 0:
            print(f"武将列表: {self.available_generals[:10]}{'...' if len(self.available_generals) > 10 else ''}")
        else:
            print("❌ 武将列表为空！请检查枚举数据和文件目录")
            # 如果为空，至少加载枚举数据
            self.available_generals = get_all_general_names()
            print(f"🔧 已恢复使用枚举数据: {len(self.available_generals)} 个武将")
            
    def create_gui(self):
        """创建GUI界面"""
        self.root = tk.Tk()
        self.root.title("三国杀自走棋 - 一体化智能识别系统")
        self.root.geometry("1000x800")
        
        # 添加窗口拖动功能
        self.setup_window_drag()
        
        # 主标题
        title = tk.Label(self.root, text="一体化智能武将管理系统", 
                        font=("Arial", 16, "bold"))
        title.pack(pady=5)
        
        # 状态显示
        self.status_var = tk.StringVar()
        self.status_var.set("准备就绪")
        status_label = tk.Label(self.root, textvariable=self.status_var, 
                               fg="blue", font=("Arial", 12))
        status_label.pack(pady=3)
        
        # 创建界面切换按钮
        switch_frame = tk.Frame(self.root)
        switch_frame.pack(fill=tk.X, padx=10, pady=(5,0))
        
        self.calibration_btn = tk.Button(switch_frame, text="🔧 区域标定", 
                                       command=self.show_calibration_interface,
                                       bg="lightgreen", font=("Arial", 12, "bold"),
                                       width=15, height=2)
        self.calibration_btn.pack(side=tk.LEFT, padx=5)
        
        self.recognition_btn = tk.Button(switch_frame, text="🎯 智能识别", 
                                       command=self.show_recognition_interface,
                                       bg="lightblue", font=("Arial", 12, "bold"),
                                       width=15, height=2)
        self.recognition_btn.pack(side=tk.LEFT, padx=5)
        
        # 创建主内容区域
        self.main_content_frame = tk.Frame(self.root)
        self.main_content_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=(5,0))
        
        print("🔧 创建界面框架...")
        
        # 创建两个界面框架但不显示
        self.calibration_frame = tk.Frame(self.main_content_frame)
        self.recognition_frame = tk.Frame(self.main_content_frame)
        
        # 创建界面内容
        self.create_calibration_interface()
        print("✅ 区域标定界面已创建")
        
        self.create_recognition_interface()
        print("✅ 智能识别界面已创建")
        
        # 根据标定状态显示对应界面
        if self.calibration_mode:
            self.show_calibration_interface()
            print("🔧 显示区域标定界面")
        else:
            self.show_recognition_interface()
            print("🎯 显示智能识别界面")
            
        # 底部日志区域
        log_frame = tk.Frame(self.root)
        log_frame.pack(fill=tk.X, pady=(5,5), padx=10, side=tk.BOTTOM)
        
        tk.Label(log_frame, text="操作日志:").pack(anchor=tk.W)
        
        self.log_text = scrolledtext.ScrolledText(log_frame, height=4, width=120)
        self.log_text.pack(fill=tk.X)
        
    def show_calibration_interface(self):
        """显示区域标定界面"""
        # 隐藏识别界面，显示标定界面
        self.recognition_frame.pack_forget()
        self.calibration_frame.pack(fill=tk.BOTH, expand=True)
        
        # 更新按钮状态
        self.calibration_btn.config(bg="orange", state=tk.DISABLED)
        self.recognition_btn.config(bg="lightblue", state=tk.NORMAL)
        
        self.log("切换到区域标定界面")
        
    def show_recognition_interface(self):
        """显示智能识别界面"""
        # 隐藏标定界面，显示识别界面
        self.calibration_frame.pack_forget()
        self.recognition_frame.pack(fill=tk.BOTH, expand=True)
        
        # 更新按钮状态
        self.recognition_btn.config(bg="orange", state=tk.DISABLED)
        self.calibration_btn.config(bg="lightgreen", state=tk.NORMAL)
        
        self.log("切换到智能识别界面")
        
    def create_calibration_interface(self):
        """创建标定界面"""
        # 清空之前的内容
        for widget in self.calibration_frame.winfo_children():
            widget.destroy()
            
        # 说明文字
        instruction = tk.Label(self.calibration_frame, 
                              text="🎯 区域标定 - 点击按钮后5秒倒计时，请移动鼠标到对应位置",
                              fg="darkblue", font=("Arial", 14, "bold"))
        instruction.pack(pady=15)
        
        # 标定按钮区域 - 全部显示在顶部
        button_container = tk.Frame(self.calibration_frame)
        button_container.pack(pady=10, padx=20, fill="x")
        
        # 营帐区域按钮
        camp_frame = tk.LabelFrame(button_container, text="1. 营帐区域（招募区）", 
                                 font=("Arial", 11, "bold"), fg="green", padx=10, pady=5)
        camp_frame.pack(fill="x", pady=5)
        
        camp_btn_frame = tk.Frame(camp_frame)
        camp_btn_frame.pack()
        
        tk.Button(camp_btn_frame, text="📍 标定左上角", 
                 command=lambda: self.calibrate_point('camp', 'top_left'),
                 bg="lightgreen", font=("Arial", 10, "bold"), width=12, height=2).pack(side=tk.LEFT, padx=5)
        tk.Button(camp_btn_frame, text="📍 标定右下角", 
                 command=lambda: self.calibrate_point('camp', 'bottom_right'),
                 bg="lightgreen", font=("Arial", 10, "bold"), width=12, height=2).pack(side=tk.LEFT, padx=5)
        
        self.camp_status = tk.Label(camp_frame, text="❌ 未标定", fg="red", font=("Arial", 10))
        self.camp_status.pack()
        
        # 上阵区域按钮
        battle_frame = tk.LabelFrame(button_container, text="2. 上阵区域（战斗区）", 
                                   font=("Arial", 11, "bold"), fg="orange", padx=10, pady=5)
        battle_frame.pack(fill="x", pady=5)
        
        battle_btn_frame = tk.Frame(battle_frame)
        battle_btn_frame.pack()
        
        tk.Button(battle_btn_frame, text="📍 标定左上角", 
                 command=lambda: self.calibrate_point('battlefield', 'top_left'),
                 bg="lightyellow", font=("Arial", 10, "bold"), width=12, height=2).pack(side=tk.LEFT, padx=5)
        tk.Button(battle_btn_frame, text="📍 标定右下角", 
                 command=lambda: self.calibrate_point('battlefield', 'bottom_right'),
                 bg="lightyellow", font=("Arial", 10, "bold"), width=12, height=2).pack(side=tk.LEFT, padx=5)
        
        self.battlefield_status = tk.Label(battle_frame, text="❌ 未标定", fg="red", font=("Arial", 10))
        self.battlefield_status.pack()
        
        # 手牌区域按钮
        hand_frame = tk.LabelFrame(button_container, text="3. 手牌区域（底部区）", 
                                 font=("Arial", 11, "bold"), fg="blue", padx=10, pady=5)
        hand_frame.pack(fill="x", pady=5)
        
        hand_btn_frame = tk.Frame(hand_frame)
        hand_btn_frame.pack()
        
        tk.Button(hand_btn_frame, text="📍 标定左上角", 
                 command=lambda: self.calibrate_point('hand', 'top_left'),
                 bg="lightcyan", font=("Arial", 10, "bold"), width=12, height=2).pack(side=tk.LEFT, padx=5)
        tk.Button(hand_btn_frame, text="📍 标定右下角", 
                 command=lambda: self.calibrate_point('hand', 'bottom_right'),
                 bg="lightcyan", font=("Arial", 10, "bold"), width=12, height=2).pack(side=tk.LEFT, padx=5)
        
        self.hand_status = tk.Label(hand_frame, text="❌ 未标定", fg="red", font=("Arial", 10))
        self.hand_status.pack()
        
        # 操作按钮
        operation_frame = tk.Frame(self.calibration_frame)
        operation_frame.pack(pady=20)
        
        tk.Button(operation_frame, text="🔍 测试区域截取", 
                 command=lambda: self.run_calibration_action(self.test_regions),
                 bg="orange", fg="white", font=("Arial", 11, "bold"),
                 width=18, height=2).pack(side=tk.LEFT, padx=10)
        
        tk.Button(operation_frame, text="💾 保存标定并切换到识别", 
                 command=lambda: self.run_calibration_action(self.save_calibration_and_switch),
                 bg="red", fg="white", font=("Arial", 11, "bold"),
                 width=25, height=2).pack(side=tk.LEFT, padx=10)
        
        # 更新状态显示
        self.update_calibration_status_display()
        
        
    def create_recognition_interface(self):
        """创建识别界面"""
        # 清空之前的内容
        for widget in self.recognition_frame.winfo_children():
            widget.destroy()
            
        # 标题
        title = tk.Label(self.recognition_frame, 
                        text="🎯 智能识别与操作 - 一键识别游戏区域并执行操作",
                        fg="darkblue", font=("Arial", 14, "bold"))
        title.pack(pady=(10, 15))
        
        # 速度设置面板
        speed_frame = tk.LabelFrame(self.recognition_frame, text="⚡ 操作速度设置", 
                                   font=("Arial", 11, "bold"), padx=10, pady=8)
        speed_frame.pack(fill="x", padx=15, pady=(0, 10))
        
        self.speed_var = tk.IntVar(value=3)
        speed_container = tk.Frame(speed_frame)
        speed_container.pack()
        
        tk.Radiobutton(speed_container, text="🐌 正常速度", variable=self.speed_var, 
                      value=1, command=self.update_speed, font=("Arial", 10)).pack(side=tk.LEFT, padx=15)
        tk.Radiobutton(speed_container, text="🚀 快速模式", variable=self.speed_var, 
                      value=2, command=self.update_speed, font=("Arial", 10)).pack(side=tk.LEFT, padx=15)
        tk.Radiobutton(speed_container, text="⚡ 极速模式", variable=self.speed_var, 
                      value=3, command=self.update_speed, font=("Arial", 10)).pack(side=tk.LEFT, padx=15)
        
        # 主内容区域
        main_container = tk.Frame(self.recognition_frame)
        main_container.pack(fill=tk.BOTH, expand=True, padx=15, pady=(0, 10))
        
        # 左侧控制面板
        left_panel = tk.Frame(main_container, width=280)
        left_panel.pack(side=tk.LEFT, fill=tk.Y, padx=(0, 10))
        left_panel.pack_propagate(False)
        
        # 区域识别控制
        self.create_recognition_control_panel(left_panel)
        
        # 武将操作控制
        self.create_operation_control_panel(left_panel)
        
        # 右侧内容面板
        right_panel = tk.Frame(main_container)
        right_panel.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True)
        
        # 武将选择面板
        self.create_general_selection_panel(right_panel)
        
        # 识别结果面板
        self.create_recognition_results_panel(right_panel)
        
    def create_recognition_control_panel(self, parent):
        """创建识别控制面板"""
        control_frame = tk.LabelFrame(parent, text="🔍 区域识别", 
                                    font=("Arial", 11, "bold"), padx=8, pady=8)
        control_frame.pack(fill="x", pady=(0, 10))
        
        buttons_data = [
            ("📊 识别营帐区域", lambda: self.recognize_region('camp'), "lightgreen"),
            ("⚔️ 识别上阵区域", lambda: self.recognize_region('battlefield'), "lightyellow"),  
            ("🎴 识别手牌区域", lambda: self.recognize_region('hand'), "lightcyan"),
            ("🌟 识别所有区域", self.recognize_all_regions, "orange")
        ]
        
        for text, command, color in buttons_data:
            btn = tk.Button(control_frame, text=text, 
                           command=lambda cmd=command: self.run_action(cmd),
                           bg=color, font=("Arial", 9, "bold"),
                           width=22, height=2)
            btn.pack(pady=3, fill="x")
            
    def create_operation_control_panel(self, parent):
        """创建操作控制面板"""
        operation_frame = tk.LabelFrame(parent, text="🎮 武将操作", 
                                      font=("Arial", 11, "bold"), padx=8, pady=8)
        operation_frame.pack(fill="x", pady=(0, 10))
        
        buttons_data = [
            ("⬇️ 招募选中武将", self.recruit_selected, "lightgreen"),
            ("⬆️ 遣散选中武将", self.dismiss_selected, "lightcoral"),
            ("➡️ 上阵选中武将", self.deploy_selected, "lightblue"),
            ("⏹️ 停止所有操作", self.stop_all, "red")
        ]
        
        for text, command, color in buttons_data:
            fg_color = "white" if color == "red" else "black"
            btn = tk.Button(operation_frame, text=text,
                           command=lambda cmd=command: self.run_action(cmd) if cmd != self.stop_all else cmd(),
                           bg=color, fg=fg_color, font=("Arial", 9, "bold"),
                           width=22, height=2)
            btn.pack(pady=3, fill="x")
            
    def create_general_selection_panel(self, parent):
        """创建武将选择面板"""
        select_frame = tk.LabelFrame(parent, text="🎭 武将选择列表", 
                                   font=("Arial", 11, "bold"), padx=8, pady=8)
        select_frame.pack(fill="x", pady=(0, 10))
        
        # 控制按钮
        btn_container = tk.Frame(select_frame)
        btn_container.pack(fill="x", pady=(0, 8))
        
        tk.Button(btn_container, text="✅ 全选", command=self.select_all_generals,
                 bg="lightgreen", font=("Arial", 9, "bold"), width=8, height=1).pack(side=tk.LEFT, padx=3)
        tk.Button(btn_container, text="❌ 取消全选", command=self.deselect_all_generals,
                 bg="lightcoral", font=("Arial", 9, "bold"), width=8, height=1).pack(side=tk.LEFT, padx=3)
        
        # 武将列表滚动区域
        list_container = tk.Frame(select_frame, height=100)
        list_container.pack(fill="x", pady=(0, 5))
        list_container.pack_propagate(False)
        
        self.select_canvas = tk.Canvas(list_container, bg="white", highlightthickness=1, highlightcolor="gray")
        select_scrollbar = tk.Scrollbar(list_container, orient="vertical", command=self.select_canvas.yview)
        self.select_scrollable = tk.Frame(self.select_canvas, bg="white")
        
        self.select_canvas.configure(yscrollcommand=select_scrollbar.set)
        self.select_canvas.pack(side="left", fill="both", expand=True)
        select_scrollbar.pack(side="right", fill="y")
        
        self.select_canvas.create_window((0, 0), window=self.select_scrollable, anchor="nw")
        
        # 初始化武将选择
        self.general_selection_vars = {}
        self.selected_general_names = set()
        
        self.create_general_selection_checkboxes()
        self.root.after(100, self.refresh_general_selection)
        
    def create_recognition_results_panel(self, parent):
        """创建识别结果面板"""
        results_frame = tk.LabelFrame(parent, text="📋 识别结果", 
                                    font=("Arial", 11, "bold"), padx=8, pady=8)
        results_frame.pack(fill="both", expand=True)
        
        # 创建三个区域的结果显示
        regions_data = [
            ("营帐区域", "camp", "lightgreen"),
            ("上阵区域", "battlefield", "lightyellow"), 
            ("手牌区域", "hand", "lightcyan")
        ]
        
        for name, region_type, color in regions_data:
            self.create_region_result_panel(results_frame, name, region_type, color)
            
    def create_region_result_panel(self, parent, name, region_type, color):
        """创建单个区域结果面板"""
        frame = tk.LabelFrame(parent, text=f"📍 {name}",
                            font=("Arial", 10, "bold"), padx=5, pady=5)
        frame.pack(fill="x", pady=3)
        
        # 状态和按钮
        control_frame = tk.Frame(frame)
        control_frame.pack(fill="x", pady=2)
        
        status_label = tk.Label(control_frame, text="等待识别...", fg="gray", font=("Arial", 9))
        status_label.pack(side=tk.LEFT)
        
        tk.Button(control_frame, text="✅ 全选", 
                 command=lambda: self.select_all_in_region(region_type),
                 bg="lightgreen", font=("Arial", 8), width=6, height=1).pack(side=tk.RIGHT, padx=2)
        tk.Button(control_frame, text="❌ 清空", 
                 command=lambda: self.deselect_all_in_region(region_type),
                 bg="lightcoral", font=("Arial", 8), width=6, height=1).pack(side=tk.RIGHT, padx=2)
        
        # 结果显示区域
        result_frame = tk.Frame(frame, height=60, bg="white", relief=tk.SUNKEN, bd=1)
        result_frame.pack(fill="x", pady=2)
        result_frame.pack_propagate(False)
        
        result_label = tk.Label(result_frame, text="暂无识别结果", 
                              fg="lightgray", bg="white", font=("Arial", 9))
        result_label.pack(expand=True)
        
        # 保存引用
        setattr(self, f"{region_type}_result_frame", result_frame)
        setattr(self, f"{region_type}_result_label", result_label)
        setattr(self, f"{region_type}_status_label", status_label)
        
    def create_general_panels(self, parent):
        """创建武将选择面板"""
        # 营帐区域武将
        self.create_region_panel(parent, 'camp', '营帐区域武将', 'lightgreen')
        
        # 上阵区域武将
        self.create_region_panel(parent, 'battlefield', '上阵区域武将', 'yellow')
        
        # 手牌区域武将
        self.create_region_panel(parent, 'hand', '手牌区域武将', 'lightblue')
        
    def create_region_panel(self, parent, region_type, title, color):
        """创建单个区域面板"""
        frame = tk.LabelFrame(parent, text=title, padx=5, pady=5)
        frame.pack(fill="x", pady=3)
        
        # 按钮框架
        btn_frame = tk.Frame(frame)
        btn_frame.pack(fill="x", pady=2)
        
        tk.Button(btn_frame, text="全选", 
                 command=lambda: self.select_all_in_region(region_type),
                 bg="lightgreen", width=8).pack(side=tk.LEFT, padx=2)
        tk.Button(btn_frame, text="取消", 
                 command=lambda: self.deselect_all_in_region(region_type),
                 bg="lightcoral", width=8).pack(side=tk.LEFT, padx=2)
        
        # 滚动区域
        canvas_frame = tk.Frame(frame, height=80)
        canvas_frame.pack(fill="x", pady=2)
        canvas_frame.pack_propagate(False)
        
        canvas = tk.Canvas(canvas_frame, height=80, bg="white", highlightthickness=0)
        scrollbar = tk.Scrollbar(canvas_frame, orient="vertical", command=canvas.yview)
        scrollable = tk.Frame(canvas, bg="white")
        
        canvas.configure(yscrollcommand=scrollbar.set)
        canvas.pack(side="left", fill="both", expand=True)
        scrollbar.pack(side="right", fill="y")
        
        canvas.create_window((0, 0), window=scrollable, anchor="nw")
        
        # 存储引用
        setattr(self, f"{region_type}_canvas", canvas)
        setattr(self, f"{region_type}_scrollable", scrollable)
        setattr(self, f"{region_type}_vars", {})
        
        # 初始提示
        tk.Label(scrollable, text="请先识别该区域", fg="gray", bg="white").pack(pady=20)
        
    def setup_window_drag(self):
        """设置窗口拖动功能"""
        def start_move(event):
            self.root.x = event.x
            self.root.y = event.y
            
        def stop_move(event):
            self.root.x = None
            self.root.y = None
            
        def do_move(event):
            if hasattr(self.root, 'x') and self.root.x is not None:
                deltax = event.x - self.root.x
                deltay = event.y - self.root.y
                x = self.root.winfo_x() + deltax
                y = self.root.winfo_y() + deltay
                self.root.geometry(f"+{x}+{y}")
        
        self.root.bind('<Button-1>', start_move)
        self.root.bind('<ButtonRelease-1>', stop_move)
        self.root.bind('<B1-Motion>', do_move)
        
        # 空格键紧急停止功能
        self.root.bind('<KeyPress-space>', self.emergency_stop)
        self.root.focus_set()  # 设置焦点以接收键盘事件
        
    def create_general_selection_checkboxes(self):
        """创建武将选择复选框"""
        # 清除现有内容
        for widget in self.select_scrollable.winfo_children():
            widget.destroy()
            
        if not self.available_generals:
            tk.Label(self.select_scrollable, text="未加载武将数据", 
                    fg="gray", bg="white").pack(pady=20)
            return
            
        # 创建复选框，按4列排列
        cols = 4
        for i, general_name in enumerate(self.available_generals):
            var = tk.BooleanVar()
            self.general_selection_vars[general_name] = var
            
            cb = tk.Checkbutton(self.select_scrollable, text=general_name, 
                               variable=var, bg="white",
                               command=lambda g=general_name: self.toggle_general_selection_main(g))
            
            row = i // cols
            col = i % cols
            cb.grid(row=row, column=col, sticky="w", padx=5, pady=2)
            
        # 更新滚动区域
        self.select_scrollable.update_idletasks()
        self.select_canvas.configure(scrollregion=self.select_canvas.bbox("all"))
        
    def refresh_general_selection(self):
        """刷新武将选择列表显示"""
        print(f"🔄 刷新武将选择列表，当前武将数量: {len(self.available_generals)}")
        if hasattr(self, 'select_scrollable'):
            self.create_general_selection_checkboxes()
        
    def toggle_general_selection_main(self, general_name):
        """切换主武将选择状态"""
        if self.general_selection_vars[general_name].get():
            self.selected_general_names.add(general_name)
        else:
            self.selected_general_names.discard(general_name)
            
        self.log(f"当前选择武将: {len(self.selected_general_names)} 个")
        
    def select_all_generals(self):
        """全选武将"""
        for general_name, var in self.general_selection_vars.items():
            var.set(True)
            self.selected_general_names.add(general_name)
        self.log(f"已全选 {len(self.selected_general_names)} 个武将")
        
    def deselect_all_generals(self):
        """取消全选武将"""
        for general_name, var in self.general_selection_vars.items():
            var.set(False)
        self.selected_general_names.clear()
        self.log("已取消所有武将选择")
        
    def log(self, message):
        """输出日志"""
        timestamp = time.strftime("%H:%M:%S")
        log_msg = f"[{timestamp}] {message}\n"
        print(log_msg.strip())
        try:
            self.log_text.insert(tk.END, log_msg)
            self.log_text.see(tk.END)
        except:
            pass
            
    def run_action(self, action):
        """在线程中运行识别操作"""
        threading.Thread(target=action, daemon=True).start()
        
    def run_calibration_action(self, action):
        """在线程中运行标定操作"""
        threading.Thread(target=action, daemon=True).start()
        
    def calibrate_point(self, region_type, point_type):
        """标定区域的一个点"""
        region_name = self.regions[region_type]['name']
        point_name = "左上角" if point_type == 'top_left' else "右下角"
        
        self.log(f"开始标定{region_name}{point_name}")
        self.status_var.set(f"标定{region_name}{point_name}中...")
        
        # 开始5秒倒计时
        self.start_countdown(region_type, point_type, 5)
        
    def start_countdown(self, region_type, point_type, countdown):
        """开始倒计时标定"""
        region_name = self.regions[region_type]['name']
        point_name = "左上角" if point_type == 'top_left' else "右下角"
        
        if countdown > 0:
            self.log(f"倒计时: {countdown} 秒 - 请将鼠标移动到{region_name}{point_name}")
            self.status_var.set(f"倒计时: {countdown} 秒 - 标定{region_name}{point_name}")
            
            # 使用after方法在1秒后继续倒计时，不会阻塞界面
            self.root.after(1000, lambda: self.start_countdown(region_type, point_type, countdown - 1))
        else:
            # 倒计时结束，获取鼠标位置
            self.finish_calibration(region_type, point_type)
    
    def finish_calibration(self, region_type, point_type):
        """完成标定，获取鼠标位置"""
        region_name = self.regions[region_type]['name']
        point_name = "左上角" if point_type == 'top_left' else "右下角"
        
        # 获取当前鼠标位置
        x, y = pyautogui.position()
        self.regions[region_type][point_type] = {'x': x, 'y': y}
        
        self.log(f"✅ {region_name}{point_name}标定完成: ({x}, {y})")
        self.status_var.set("标定完成")
        
        # 更新状态显示
        self.update_calibration_status_display()
        
    def update_calibration_status_display(self):
        """更新标定状态显示"""
        # 使用固定的属性名，对应新界面中创建的标签
        status_mappings = {
            'camp': 'camp_status',
            'battlefield': 'battlefield_status', 
            'hand': 'hand_status'
        }
        
        for region_type, status_attr in status_mappings.items():
            if hasattr(self, status_attr):
                status_label = getattr(self, status_attr)
                region = self.regions[region_type]
                
                if region['top_left'] and region['bottom_right']:
                    status_label.config(text="✅ 已完成标定", fg="green")
                elif region['top_left'] or region['bottom_right']:
                    status_label.config(text="⚠️ 部分完成", fg="orange")
                else:
                    status_label.config(text="❌ 未标定", fg="red")
            else:
                print(f"⚠️ 未找到状态标签: {status_attr}")
                
    def test_regions(self):
        """测试区域截取"""
        self.log("=== 开始测试区域截取 ===")
        self.status_var.set("测试截取中...")
        
        screenshot = pyautogui.screenshot()
        screenshot_cv = cv2.cvtColor(np.array(screenshot), cv2.COLOR_RGB2BGR)
        
        for region_type, region in self.regions.items():
            if not (region['top_left'] and region['bottom_right']):
                self.log(f"⚠️ {region['name']}未完成标定，跳过")
                continue
                
            # 转换为物理坐标
            left = int(region['top_left']['x'] * self.scale_x)
            top = int(region['top_left']['y'] * self.scale_y)
            right = int(region['bottom_right']['x'] * self.scale_x)
            bottom = int(region['bottom_right']['y'] * self.scale_y)
            
            # 截取区域
            try:
                region_img = screenshot_cv[top:bottom, left:right]
                filename = f"{region_type}_region_test.png"
                cv2.imwrite(filename, region_img)
                
                width = right - left
                height = bottom - top
                self.log(f"✅ {region['name']}截取成功: {filename} ({width}x{height})")
                
            except Exception as e:
                self.log(f"❌ {region['name']}截取失败: {e}")
                
        self.status_var.set("测试完成")
                
    def save_calibration_and_switch(self):
        """保存标定结果并切换到识别界面"""
        # 检查是否所有区域都已标定
        incomplete_regions = []
        for region_type, region in self.regions.items():
            if not (region['top_left'] and region['bottom_right']):
                incomplete_regions.append(region['name'])
                
        if incomplete_regions:
            messagebox.showwarning("标定未完成", f"以下区域未完成标定:\n" + "\n".join(incomplete_regions))
            return
            
        # 保存到文件
        calibration_data = {
            'screen_resolution': f"{self.logical_width}x{self.logical_height}",
            'physical_resolution': f"{self.physical_width}x{self.physical_height}",
            'scale': {'x': self.scale_x, 'y': self.scale_y},
            'regions': self.regions,
            'timestamp': time.strftime("%Y-%m-%d %H:%M:%S")
        }
        
        try:
            with open("region_calibration.json", "w", encoding="utf-8") as f:
                json.dump(calibration_data, f, indent=2, ensure_ascii=False)
                
            self.log("✅ 标定结果已保存到 region_calibration.json")
            self.calibration_data = calibration_data
            self.calibration_mode = False
            
            # 切换到识别界面
            self.show_recognition_interface()
            self.status_var.set("标定完成，可以开始识别")
            
            messagebox.showinfo("保存成功", "区域标定结果已保存，已切换到识别界面!")
            
        except Exception as e:
            self.log(f"❌ 保存失败: {e}")
            messagebox.showerror("保存失败", f"保存标定结果时出错: {e}")
            
    def update_speed(self):
        """更新速度设置"""
        self.speed_setting = self.speed_var.get()
        speed_text = "极速模式" if self.speed_setting == 3 else ("快速模式" if self.speed_setting == 2 else "正常速度")
        self.log(f"操作速度设置: {speed_text}")
        
    def get_speed_delays(self):
        """根据速度设置获取延时时间 - 完全恢复backup版本的工作参数"""
        if self.speed_setting == 3:  # 极速模式 - 保守调整，确保能工作
            return {
                'move_duration': 0.01,   # 介于快速模式和正常模式之间，更安全
                'click_delay': 0.01,     # 稍微增加延时确保武将被选中
                'drag_duration': 0.4,    # 接近快速模式，确保游戏能识别：注意这里必须大于0.4，不然招募不到
                'between_actions': 0.01   # 足够的间隔确保操作完成
            }
        elif self.speed_setting == 2:  # 快速模式 - 完全使用backup版本参数
            return {
                'move_duration': 0.2,
                'click_delay': 0.1,
                'drag_duration': 0.4,
                'between_actions': 1.0
            }
        else:  # 正常速度 - 完全使用backup版本参数  
            return {
                'move_duration': 0.3,
                'click_delay': 0.2,
                'drag_duration': 0.8,
                'between_actions': 2.0
            }
            
    def recognize_region(self, region_type):
        """识别指定区域的武将"""
        if not self.regions or region_type not in self.regions:
            messagebox.showwarning("警告", "请先完成区域标定")
            return
            
        region = self.regions[region_type]
        if not (region.get('top_left') and region.get('bottom_right')):
            self.log(f"❌ {region['name']}区域标定不完整")
            return
            
        self.log(f"=== 开始识别{region['name']} ===")
        self.status_var.set(f"识别{region['name']}中...")
        
        try:
            # 截取区域
            screenshot = pyautogui.screenshot()
            screenshot_cv = cv2.cvtColor(np.array(screenshot), cv2.COLOR_RGB2BGR)
            
            # 转换为物理坐标
            left = int(region['top_left']['x'] * self.scale_x)
            top = int(region['top_left']['y'] * self.scale_y)
            right = int(region['bottom_right']['x'] * self.scale_x)
            bottom = int(region['bottom_right']['y'] * self.scale_y)
            
            region_img = screenshot_cv[top:bottom, left:right]
            
            # 保存调试图片
            debug_filename = f"{region_type}_region_debug.png"
            cv2.imwrite(debug_filename, region_img)
            
            # OCR识别
            if self.ocr_reader is None:
                self.log("❌ OCR未初始化")
                return
                
            results = self.ocr_reader.readtext(region_img)
            
            # 打印所有OCR识别结果用于调试
            self.log(f"OCR识别到 {len(results)} 个文本")
            for (bbox, text, conf) in results:
                if conf > 0.3:
                    self.log(f"  - 文本: '{text}' 置信度: {conf:.2f}")
            
            # 势力标签列表（需要排除的）
            faction_labels = ['魏', '蜀', '吴', '汉', '袁', '黄巾', '西凉', '群', '晋']
            
            # 解析OCR结果，匹配武将名称
            region_generals = []
            general_positions = []  # 记录已识别武将的位置
            
            for (bbox, text, confidence) in results:
                if confidence < 0.3:  # 置信度太低，跳过
                    continue
                    
                # 清理文本（去除空格和特殊字符）
                clean_text = text.strip().replace(' ', '').replace('·', '')
                
                # 处理常见的OCR识别错误
                ocr_corrections = {
                    '冯方': '冯芳',  # 方/芳 容易识别错误
                }
                if clean_text in ocr_corrections:
                    self.log(f"    纠正OCR错误: '{clean_text}' -> '{ocr_corrections[clean_text]}'")
                    clean_text = ocr_corrections[clean_text]
                
                # 排除单个字符
                if len(clean_text) <= 1:
                    continue
                    
                # 计算文本位置
                bbox_center_x = (bbox[0][0] + bbox[2][0]) // 2
                bbox_center_y = (bbox[0][1] + bbox[2][1]) // 2
                
                # 检查是否是势力标签（在已识别武将的正下方）
                is_faction_label = False
                if clean_text in faction_labels:
                    for gen_pos in general_positions:
                        # 如果这个文本在某个武将的正下方（X坐标相近，Y坐标差20-60像素）
                        if abs(bbox_center_x - gen_pos[0]) < 30 and 20 < (bbox_center_y - gen_pos[1]) < 60:
                            self.log(f"    排除势力标签: '{clean_text}' (在武将下方)")
                            is_faction_label = True
                            break
                    if not is_faction_label and clean_text in faction_labels:
                        # 独立的势力标签也排除
                        self.log(f"    排除势力标签: '{clean_text}'")
                        continue
                
                if is_faction_label:
                    continue
                    
                # 在武将列表中查找匹配的武将
                matched_general = None
                best_match_score = 0
                
                for general_name in self.available_generals:
                    # 完全匹配优先
                    if general_name == clean_text:
                        matched_general = general_name
                        best_match_score = 1.0
                        break
                    # 武将名在识别文本中（允许有其他字符）
                    elif general_name in clean_text:
                        score = len(general_name) / len(clean_text)
                        if score > best_match_score and score > 0.5:  # 至少占50%
                            matched_general = general_name
                            best_match_score = score
                    # 识别文本在武将名中（可能识别不全）
                    elif clean_text in general_name and len(clean_text) >= 2:
                        score = len(clean_text) / len(general_name)
                        if score > best_match_score and score > 0.6:  # 至少识别60%
                            matched_general = general_name
                            best_match_score = score
                
                if matched_general:
                    # 转换为逻辑坐标（bbox_center_x/y已经在前面计算过了）
                    screen_x = region['top_left']['x'] + int(bbox_center_x / self.scale_x)
                    screen_y = region['top_left']['y'] + int(bbox_center_y / self.scale_y)
                    
                    # 检查是否与已有武将位置太近（避免同一武将重复识别）
                    is_duplicate = False
                    for existing in region_generals:
                        if abs(existing['screen_pos'][0] - screen_x) < 20 and \
                           abs(existing['screen_pos'][1] - screen_y) < 20:
                            is_duplicate = True
                            break
                    
                    if not is_duplicate:
                        region_generals.append({
                            'name': matched_general,
                            'text': text,
                            'confidence': confidence,
                            'screen_pos': (screen_x, screen_y),
                            'region_pos': (bbox_center_x, bbox_center_y),
                            'bbox': bbox
                        })
                        
                        self.log(f"✅ 发现武将: {matched_general} 在 ({screen_x}, {screen_y}) 置信度: {confidence:.2f}")
                        # 记录武将位置，用于排除下方的势力标签
                        general_positions.append((bbox_center_x, bbox_center_y))
                else:
                    # 调试：显示未匹配的文本
                    if len(clean_text) >= 2 and not any(keyword in clean_text for keyword in ['当先', '战斗', '友方', '攻击', '伤害', '开启', '获得', '使其']):
                        self.log(f"    ⚠️ 未匹配: '{clean_text}' (可能是新武将或识别错误)")
                        
            # 存储识别结果
            self.region_generals[region_type] = region_generals
            
            self.log(f"✅ {region['name']}识别完成，发现 {len(region_generals)} 个武将")
            self.status_var.set(f"{region['name']}识别完成: {len(region_generals)}个武将")
            
            # 在主线程中更新界面显示
            self.root.after(0, lambda: self.update_region_display(region_type))
            
        except Exception as e:
            self.log(f"❌ {region['name']}识别失败: {e}")
            import traceback
            traceback.print_exc()
            self.status_var.set("识别失败")
            
    def recognize_all_regions(self):
        """识别所有区域"""
        self.log("=== 开始识别所有区域 ===")
        delays = self.get_speed_delays()
        for region_type in ['camp', 'battlefield', 'hand']:
            self.recognize_region(region_type)
            time.sleep(delays['between_actions'] * 0.3)  # 识别间隔
        self.log("✅ 所有区域识别完成")
        
    def update_region_display(self, region_type):
        """更新区域显示"""
        # 获取识别结果组件
        result_frame_attr = f"{region_type}_result_frame"
        result_label_attr = f"{region_type}_result_label" 
        status_label_attr = f"{region_type}_status_label"
        
        # 检查组件是否存在
        if not (hasattr(self, result_frame_attr) and hasattr(self, result_label_attr) and hasattr(self, status_label_attr)):
            print(f"⚠️ 识别结果组件不存在: {region_type}")
            return
            
        result_frame = getattr(self, result_frame_attr)
        result_label = getattr(self, result_label_attr)
        status_label = getattr(self, status_label_attr)
        
        # 清除现有内容
        for widget in result_frame.winfo_children():
            widget.destroy()
            
        # 更新状态标签
        generals = self.region_generals.get(region_type, [])
        if not generals:
            status_label.config(text="未识别到武将", fg="gray")
            result_label = tk.Label(result_frame, text="暂无识别结果", 
                                  fg="lightgray", bg="white", font=("Arial", 9))
            result_label.pack(expand=True)
            setattr(self, result_label_attr, result_label)  # 保存引用
        else:
            status_label.config(text=f"识别到 {len(generals)} 个武将", fg="green")
            
            # 创建武将选择复选框
            vars_dict = {}
            setattr(self, f"{region_type}_vars", vars_dict)
            
            # 使用网格布局显示武将
            cols = 3  # 每行3个
            for i, general in enumerate(generals):
                var = tk.BooleanVar()
                vars_dict[general['name']] = var
                
                cb = tk.Checkbutton(result_frame, text=f"{general['name']}", 
                                   variable=var, bg="white", font=("Arial", 9),
                                   command=lambda g=general['name'], r=region_type, v=var: 
                                   self.toggle_general_selection(r, g, v))
                row = i // cols
                col = i % cols  
                cb.grid(row=row, column=col, sticky="w", padx=2, pady=1)
        
    def toggle_general_selection(self, region_type, general_name, var):
        """切换武将选择状态"""
        if var.get():
            self.selected_generals[region_type].add(general_name)
        else:
            self.selected_generals[region_type].discard(general_name)
            
        total_selected = sum(len(s) for s in self.selected_generals.values())
        self.log(f"当前选择武将总数: {total_selected}")
        
    def select_all_in_region(self, region_type):
        """选中区域内所有武将"""
        vars_dict = getattr(self, f"{region_type}_vars")
        for general_name, var in vars_dict.items():
            var.set(True)
            self.selected_generals[region_type].add(general_name)
        self.log(f"全选{region_type}区域 {len(vars_dict)} 个武将")
        
    def deselect_all_in_region(self, region_type):
        """取消选中区域内所有武将"""
        vars_dict = getattr(self, f"{region_type}_vars")
        for general_name, var in vars_dict.items():
            var.set(False)
        self.selected_generals[region_type].clear()
        self.log(f"取消选中{region_type}区域所有武将")
        
    def recruit_selected(self):
        """招募选中的武将到手牌"""
        if not self.selected_general_names:
            messagebox.showwarning("警告", "请先在武将选择列表中选择要招募的武将")
            return
            
        if not self.region_generals['camp']:
            messagebox.showwarning("警告", "请先识别营帐区域以获取可招募的武将")
            return
            
        self.log("=== 开始招募操作 ===")
        self.status_var.set("招募中...")
        
        # 设置运行状态
        self.running = True
        
        # 激活游戏窗口
        self.activate_game_window()
        
        # 获取速度设置
        delays = self.get_speed_delays()
        
        recruited_count = 0
        
        # 获取手牌区域的中心位置
        hand_region = self.regions.get('hand')
        if not hand_region:
            self.log("❌ 未找到手牌区域标定")
            return
            
        hand_center_x = (hand_region['top_left']['x'] + hand_region['bottom_right']['x']) // 2
        hand_center_y = (hand_region['top_left']['y'] + hand_region['bottom_right']['y']) // 2
        
        for general in self.region_generals['camp']:
            # 检查是否需要停止
            if not self.running:
                self.log("❌ 操作已停止")
                return
                
            # 检查这个武将是否在用户选择的武将列表中
            if general['name'] not in self.selected_general_names:
                continue
                
            self.log(f"招募武将: {general['name']}")
            
            from_x, from_y = general['screen_pos']
            to_x, to_y = hand_center_x, hand_center_y
            
            # 执行拖拽操作
            self.perform_drag_operation(from_x, from_y, to_x, to_y, delays)
            
            recruited_count += 1
            
            # 快速间隔延时，同时保持响应性
            if delays['between_actions'] > 0:
                time.sleep(delays['between_actions'])
            
        self.log(f"✅ 招募完成，共招募 {recruited_count} 个武将")
        self.status_var.set("招募完成")
        
    def dismiss_selected(self):
        """遣散选中的手牌武将到营帐"""
        if not self.selected_generals['hand']:
            messagebox.showwarning("警告", "请先在手牌区域识别结果中选择要遣散的武将")
            return
            
        self.log("=== 开始遣散操作 ===")
        self.status_var.set("阃散中...")
        
        # 设置运行状态
        self.running = True
        
        # 激活游戏窗口
        self.activate_game_window()
        
        # 获取速度设置
        delays = self.get_speed_delays()
        
        dismissed_count = 0
        
        # 获取营帐区域的中心位置
        camp_region = self.regions.get('camp')
        if not camp_region:
            self.log("❌ 未找到营帐区域标定")
            return
            
        camp_center_x = (camp_region['top_left']['x'] + camp_region['bottom_right']['x']) // 2
        camp_center_y = (camp_region['top_left']['y'] + camp_region['bottom_right']['y']) // 2
        
        for general in self.region_generals['hand']:
            # 检查是否需要停止
            if not self.running:
                self.log("❌ 操作已停止")
                return
                
            if general['name'] not in self.selected_generals['hand']:
                continue
                
            self.log(f"遣散武将: {general['name']}")
            
            from_x, from_y = general['screen_pos']
            to_x, to_y = camp_center_x, camp_center_y
            
            # 执行拖拽操作
            self.perform_drag_operation(from_x, from_y, to_x, to_y, delays)
            
            dismissed_count += 1
            time.sleep(delays['between_actions'])
            
        self.log(f"✅ 遣散完成，共遣散 {dismissed_count} 个武将")
        self.status_var.set("遣散完成")
        
    def deploy_selected(self):
        """上阵选中的手牌武将"""
        if not self.selected_generals['hand']:
            messagebox.showwarning("警告", "请先在手牌区域识别结果中选择要上阵的武将")
            return
            
        self.log("=== 开始上阵操作 ===")
        self.status_var.set("上阵中...")
        
        # 设置运行状态
        self.running = True
        
        # 激活游戏窗口
        self.activate_game_window()
        
        # 获取速度设置
        delays = self.get_speed_delays()
        
        deployed_count = 0
        
        # 获取上阵区域的位置
        battlefield_region = self.regions.get('battlefield')
        if not battlefield_region:
            self.log("❌ 未找到上阵区域标定")
            return
            
        battlefield_center_x = (battlefield_region['top_left']['x'] + battlefield_region['bottom_right']['x']) // 2
        battlefield_center_y = (battlefield_region['top_left']['y'] + battlefield_region['bottom_right']['y']) // 2
        
        for general in self.region_generals['hand']:
            # 检查是否需要停止
            if not self.running:
                self.log("❌ 操作已停止")
                return
                
            if general['name'] not in self.selected_generals['hand']:
                continue
                
            self.log(f"上阵武将: {general['name']}")
            
            from_x, from_y = general['screen_pos']
            # 为每个武将分配不同的上阵位置
            offset = deployed_count * 60  # 每个武将间隔60像素
            to_x = battlefield_center_x + offset
            to_y = battlefield_center_y
            
            # 执行拖拽操作
            self.perform_drag_operation(from_x, from_y, to_x, to_y, delays)
            
            deployed_count += 1
            time.sleep(delays['between_actions'])
            
        self.log(f"✅ 上阵完成，共上阵 {deployed_count} 个武将")
        self.status_var.set("上阵完成")
        
    def perform_drag_operation(self, from_x, from_y, to_x, to_y, delays):
        """执行拖拽操作 - 完全恢复backup版本的工作逻辑"""
        try:
            if not self.running:
                return
                
            self.log(f"拖拽: ({from_x}, {from_y}) → ({to_x}, {to_y})")
            
            # 移动到起点 - 使用backup版本的duration参数
            pyautogui.moveTo(from_x, from_y, duration=delays['move_duration'])
            time.sleep(delays['click_delay'])
            
            if not self.running:
                return
            
            # 按下鼠标
            pyautogui.mouseDown(button='left')
            time.sleep(delays['click_delay'])
            
            if not self.running:
                return
            
            # 拖拽到目标位置 - 使用backup版本的duration参数
            pyautogui.moveTo(to_x, to_y, duration=delays['drag_duration'])
            time.sleep(delays['click_delay'])
            
            if not self.running:
                return
            
            # 释放鼠标
            pyautogui.mouseUp(button='left')
            
        except Exception as e:
            self.log(f"❌ 拖拽操作失败: {e}")
            
    def activate_game_window(self):
        """激活游戏窗口获得焦点 - 完全恢复backup版本逻辑"""
        self.log("激活游戏窗口...")
        center_x = self.logical_width // 2
        center_y = self.logical_height // 2
        
        pyautogui.moveTo(center_x, center_y, duration=0.2)
        time.sleep(0.1)
        pyautogui.click()
        time.sleep(0.5)
        
    def emergency_stop(self, event=None):
        """空格键紧急停止"""
        self.running = False
        self.log("⚠️ 空格键紧急停止！")
        self.status_var.set("已紧急停止")
        
    def stop_all(self):
        """停止所有操作"""
        self.running = False
        self.log("停止所有操作")
        self.status_var.set("已停止")
        
    def run(self):
        """运行程序"""
        self.log("🚀 一体化智能识别器已启动")
        self.log(f"📊 系统信息: 逻辑分辨率 {self.logical_width}x{self.logical_height}")
        self.log(f"🎭 武将数据: 已加载 {len(self.available_generals)} 个武将")
        
        if self.calibration_mode:
            self.log("⚠️ 检测到未标定，请先点击 '🔧 区域标定' 按钮完成标定")
            self.log("💡 标定提示: 点击标定按钮后，系统会5秒倒计时，请移动鼠标到对应位置")
        else:
            self.log("✅ 已加载区域标定数据，可以点击 '🎯 智能识别' 按钮开始操作")
            self.log("🎮 操作提示: 先选择要招募的武将，然后点击识别区域，最后执行操作")
            
        self.root.mainloop()

if __name__ == "__main__":
    recognizer = UnifiedSmartRecognizer()
    recognizer.run()